﻿using UnityEngine;
using System.Collections;
using System;

public class GameUIState : MonoBehaviour
{

    public enum ShotType
    {
        EnergyShot,
        TeleportShot,
        Missile
    }

    public ShotType selectedShotType = ShotType.EnergyShot;

    private GameObject selectionMarkerObject;
    private GameObject energyShotButtonObject;
    private GameObject teleportShotButtonObject;
    private GameObject missileButtonObject;
    private GameObject resetButtonObject;
    private GameObject exitButtonObject;

    private GameObject playerObject;
    private VictoryDetection victoryDetection;
    private DeathDetection deathDetection;
    private RobotTouch robotTouch;

    private DateTime transitionTime = DateTime.MaxValue;
    private GameplayState targetGameplayState = GameplayState.Playing;
    public GameplayState currentGameplayState = GameplayState.Playing;

    public enum GameplayState
    {
        Playing,
        WonLevel,
        LostLevel,
        ExitDialog
    }


    // Use this for initialization
    void Start()
    {

        selectionMarkerObject = this.transform.FindChild("selectionMarker").gameObject;
        energyShotButtonObject = this.transform.FindChild("energyShotButton").gameObject;
        teleportShotButtonObject = this.transform.FindChild("teleportShotButton").gameObject;
        missileButtonObject = this.transform.FindChild("missileButton").gameObject;
        resetButtonObject = this.transform.FindChild("ResetButton").gameObject;
        exitButtonObject = this.transform.FindChild("exitButton").gameObject;

        playerObject = GameObject.FindGameObjectWithTag("Player");
        victoryDetection = playerObject.GetComponent<VictoryDetection>();
        deathDetection = playerObject.GetComponent<DeathDetection>();
        robotTouch = playerObject.transform.FindChild("RobotTouchReceiver").GetComponent<RobotTouch>();

        windowPosition = new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200);



    }

    // Update is called once per frame
    void Update()
    {
        energyShotButtonObject.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(40, Screen.height - 40, 10));

        teleportShotButtonObject.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(40, Screen.height - 100, 10));

        missileButtonObject.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(40, Screen.height - 160, 10));

        resetButtonObject.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(40, Screen.height - 220, 10));

        exitButtonObject.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width - 40, Screen.height - 40, 10));

        HighlightSelectedShot();

        if (targetGameplayState != currentGameplayState && transitionTime <= DateTime.Now)
        {
            ExitState();
            EnterState(targetGameplayState);
        }

        switch (currentGameplayState)
        {
            case GameplayState.Playing:

                // Exit transition
                if (exitButtonObject.GetComponent<ExitButton>().exitButtonPressed)
                {
                    exitButtonObject.GetComponent<ExitButton>().exitButtonPressed = false;
                    TransitionToState(GameplayState.ExitDialog);
                }

                // Victory transition: Wait 1.5 seconds before transitioning to WonLevel
                if (targetGameplayState != GameplayState.WonLevel && victoryDetection.VictoryDetected) TransitionToState(GameplayState.WonLevel, 1.5);

                // Loss transition: Wait 1.5 seconds before transitioning to LostLevel
                if (targetGameplayState != GameplayState.LostLevel && deathDetection.DoneBeingDestroyed) 
                {
                    print("Game UI state detects player destruction, transition beginning at " + DateTime.Now);
                    TransitionToState(GameplayState.LostLevel, 1.5);
                }

                break;
            case GameplayState.WonLevel:

                // Player can restart, go to the next level, or exit to the main menu

                break;
            case GameplayState.LostLevel:
                // Player can restart or exit to the main menu
                break;
            case GameplayState.ExitDialog:
                // Player can return to play or exit to the main menu
                break;
        }

    }

    private void TransitionToState(GameplayState gameplayState)
    {
        TransitionToState(gameplayState, 0);
    }

    private void TransitionToState(GameplayState state, double secondsDelay)
    {
        transitionTime = DateTime.Now.AddSeconds(secondsDelay);
        targetGameplayState = state;
    }

    private void EnterState(GameplayState targetGameplayState)
    {
        print("Entering " + targetGameplayState);
        currentGameplayState = targetGameplayState;

        switch (currentGameplayState)
        {
            // What's enabled?
            case GameplayState.Playing:
                // Shot buttons, reset button, exit button
                energyShotButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = true;
                teleportShotButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = true;
                missileButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = true;
                resetButtonObject.GetComponent<ResetButtonHandling>().TouchEnabled = true;
                exitButtonObject.GetComponent<ExitButton>().TouchEnabled = true;
                robotTouch.TouchEnabled = true;
                break;
            case GameplayState.WonLevel:
                // Victory reset button, next level button, victory exit to menu button
                // TODO: Store the level victory in user prefs
                windowPosition = new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200);
                PlayerPrefs.SetInt("lv_" + (Application.loadedLevel - 1), 1);
                PlayerPrefs.Save();
                break;
            case GameplayState.LostLevel:
                // Loss reset button, loss exit to menu button
                windowPosition = new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200);
                break;
            case GameplayState.ExitDialog:
                // Exit confirm, exit cancel
                windowPosition = new Rect(Screen.width / 2 - 100, Screen.height / 2 - 100, 200, 200);
                break;
        }

    }

    private void ExitState()
    {
        print("Exiting " + currentGameplayState);
        // What's disabled?
        switch (currentGameplayState)
        {
            case GameplayState.Playing:
                // Shot buttons, reset button, exit button
                energyShotButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = false;
                teleportShotButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = false;
                missileButtonObject.GetComponent<ShotSelectButton>().TouchEnabled = false;
                resetButtonObject.GetComponent<ResetButtonHandling>().TouchEnabled = false;
                exitButtonObject.GetComponent<ExitButton>().TouchEnabled = false;
                robotTouch.TouchEnabled = false;
                break;
            case GameplayState.WonLevel:
                // Victory reset button, next level button, victory exit to menu button
                break;
            case GameplayState.LostLevel:
                // Loss reset button, loss exit to menu button
                break;
            case GameplayState.ExitDialog:
                // Exit confirm, exit cancel
                break;
        }
    }

    private Rect windowPosition;

    void OnGUI()
    {
        // GUI.skin = skin;
        // TODO: Create custom skin for controls

        switch (currentGameplayState)
        {
            case GameplayState.Playing:
                break;
            case GameplayState.WonLevel:
                windowPosition = GUI.Window(0, windowPosition, WonLevelWindowGUI, "Victory!");
                break;
            case GameplayState.LostLevel:
                windowPosition = GUI.Window(0, windowPosition, LostLevelWindowGUI, "Lost!");
                break;
            case GameplayState.ExitDialog:
                windowPosition = GUI.Window(0, windowPosition, ExitDialogGUI, "Exit?");
                break;
        }
    }


    public void LostLevelWindowGUI(int windowId)
    {
        if (GUILayout.Button("Reset"))
        {
            ResetItemList.Instance.ResetItems();
            TransitionToState(GameplayState.Playing);
        }

        if (GUILayout.Button("Exit"))
        {
            ChangeToScene("menu");
        }
    }

    public void ExitDialogGUI(int windowId) 
    {
        if (GUILayout.Button("No"))
        {
            TransitionToState(GameplayState.Playing);
        }

        if (GUILayout.Button("Yes"))
        {
            ChangeToScene("menu");
        }
    }

    private void ChangeToScene(string sceneName)
    {
        TouchableList.Instance.Clear();
        ResetItemList.Instance.Clear();
        Application.LoadLevel(sceneName);
    }

    private void ChangeToScene(int sceneIndex)
    {
        TouchableList.Instance.Clear();
        ResetItemList.Instance.Clear();
        Application.LoadLevel(sceneIndex);
    }

    public void WonLevelWindowGUI(int windowId)
    {
        if (GUILayout.Button("Reset"))
        {
            ResetItemList.Instance.ResetItems();
            TransitionToState(GameplayState.Playing);
        }

        if (GUILayout.Button("Next Level"))
        {
            // TODO: Load the next level if there is one, otherwise load the final screen
            if (Application.loadedLevel == Application.levelCount - 2)
            {
                ChangeToScene(Application.loadedLevel + 1);
            }
        }

        if (GUILayout.Button("Exit"))
        {
            ChangeToScene("menu");
        }
    }

    private void HighlightSelectedShot()
    {
        selectionMarkerObject.renderer.enabled = true;
        switch (selectedShotType)
        {
            case ShotType.EnergyShot:
                selectionMarkerObject.transform.position = energyShotButtonObject.transform.position;
                break;
            case ShotType.TeleportShot:
                selectionMarkerObject.transform.position = teleportShotButtonObject.transform.position;
                break;
            case ShotType.Missile:
                selectionMarkerObject.transform.position = missileButtonObject.transform.position;
                break;
            default:
                selectionMarkerObject.renderer.enabled = false;
                break;
        }
    }
}
